using CollabApp.Domain.Entities.Game;

namespace CollabApp.Domain.Services.Game;

/// <summary>
/// 地图缩圈服务接口
/// 负责处理游戏后期的地图缩小机制，增加游戏紧张感和结局压迫感
/// 在最后30秒开始缩圈，强迫玩家向中心靠拢
/// </summary>
public interface IMapShrinkingService
{
    /// <summary>
    /// 检查是否应该开始地图缩圈
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <returns>是否应该开始缩圈</returns>
    Task<bool> ShouldStartShrinkingAsync(Guid gameId);

    /// <summary>
    /// 开始地图缩圈
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <returns>缩圈开始结果</returns>
    Task<ShrinkingStartResult> StartMapShrinkingAsync(Guid gameId);

    /// <summary>
    /// 更新地图缩圈状态
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <returns>缩圈更新结果</returns>
    Task<ShrinkingUpdateResult> UpdateMapShrinkingAsync(Guid gameId);

    /// <summary>
    /// 获取当前地图缩圈状态
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <returns>当前缩圈状态</returns>
    Task<MapShrinkingStatus> GetShrinkingStatusAsync(Guid gameId);

    /// <summary>
    /// 计算位置是否在安全区域内
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <param name="position">位置坐标</param>
    /// <returns>位置安全性检查结果</returns>
    Task<PositionSafetyResult> CheckPositionSafetyAsync(Guid gameId, Position position);

    /// <summary>
    /// 处理玩家在危险区域的伤害
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <param name="playerId">玩家ID</param>
    /// <param name="currentPosition">当前位置</param>
    /// <returns>危险区域伤害处理结果</returns>
    Task<DangerZoneDamageResult> ProcessDangerZoneDamageAsync(Guid gameId, Guid playerId, Position currentPosition);

    /// <summary>
    /// 获取缩圈影响的领地列表
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <returns>受影响的领地信息</returns>
    Task<List<AffectedTerritoryInfo>> GetAffectedTerritoriesAsync(Guid gameId);

    /// <summary>
    /// 停止地图缩圈（游戏结束时调用）
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <returns>停止结果</returns>
    Task<bool> StopMapShrinkingAsync(Guid gameId);

    /// <summary>
    /// 预测缩圈路径和时间点
    /// </summary>
    /// <param name="gameId">游戏ID</param>
    /// <returns>缩圈预测信息</returns>
    Task<ShrinkingPrediction> PredictShrinkingPathAsync(Guid gameId);
}

/// <summary>
/// 缩圈开始结果
/// </summary>
public class ShrinkingStartResult
{
    /// <summary>
    /// 操作是否成功
    /// </summary>
    public bool Success { get; set; }

    /// <summary>
    /// 缩圈开始时间
    /// </summary>
    public DateTime StartTime { get; set; }

    /// <summary>
    /// 初始安全区域
    /// </summary>
    public SafeZoneInfo InitialSafeZone { get; set; } = new();

    /// <summary>
    /// 最终安全区域
    /// </summary>
    public SafeZoneInfo FinalSafeZone { get; set; } = new();

    /// <summary>
    /// 缩圈总持续时间（秒）
    /// </summary>
    public int TotalDurationSeconds { get; set; }

    /// <summary>
    /// 危险区域每秒伤害值
    /// </summary>
    public float DangerZoneDamagePerSecond { get; set; }

    /// <summary>
    /// 受影响的玩家ID列表
    /// </summary>
    public List<Guid> AffectedPlayerIds { get; set; } = new();

    /// <summary>
    /// 错误信息
    /// </summary>
    public List<string> Errors { get; set; } = new();

    /// <summary>
    /// 提示信息
    /// </summary>
    public List<string> Messages { get; set; } = new();
}

/// <summary>
/// 缩圈更新结果
/// </summary>
public class ShrinkingUpdateResult
{
    /// <summary>
    /// 更新是否成功
    /// </summary>
    public bool Success { get; set; }

    /// <summary>
    /// 当前安全区域
    /// </summary>
    public SafeZoneInfo CurrentSafeZone { get; set; } = new();

    /// <summary>
    /// 缩圈进度（0-1）
    /// </summary>
    public float Progress { get; set; }

    /// <summary>
    /// 剩余时间（秒）
    /// </summary>
    public int RemainingSeconds { get; set; }

    /// <summary>
    /// 当前缩圈阶段
    /// </summary>
    public ShrinkingPhase CurrentPhase { get; set; }

    /// <summary>
    /// 在危险区域的玩家ID列表
    /// </summary>
    public List<Guid> PlayersInDangerZone { get; set; } = new();

    /// <summary>
    /// 被消除的领地数量
    /// </summary>
    public int EliminatedTerritoriesCount { get; set; }

    /// <summary>
    /// 消除的领地面积
    /// </summary>
    public float EliminatedTerritoryArea { get; set; }

    /// <summary>
    /// 更新详情
    /// </summary>
    public List<string> UpdateDetails { get; set; } = new();

    /// <summary>
    /// 警告信息
    /// </summary>
    public List<string> Warnings { get; set; } = new();
}

/// <summary>
/// 地图缩圈状态
/// </summary>
public class MapShrinkingStatus
{
    /// <summary>
    /// 是否正在缩圈
    /// </summary>
    public bool IsShrinking { get; set; }

    /// <summary>
    /// 缩圈开始时间
    /// </summary>
    public DateTime? StartTime { get; set; }

    /// <summary>
    /// 当前安全区域
    /// </summary>
    public SafeZoneInfo CurrentSafeZone { get; set; } = new();

    /// <summary>
    /// 目标安全区域
    /// </summary>
    public SafeZoneInfo TargetSafeZone { get; set; } = new();

    /// <summary>
    /// 缩圈进度（0-1）
    /// </summary>
    public float Progress { get; set; }

    /// <summary>
    /// 缩圈阶段
    /// </summary>
    public ShrinkingPhase Phase { get; set; }

    /// <summary>
    /// 剩余时间（秒）
    /// </summary>
    public int RemainingSeconds { get; set; }

    /// <summary>
    /// 危险区域伤害值
    /// </summary>
    public float DangerZoneDamage { get; set; }

    /// <summary>
    /// 在危险区域的玩家数量
    /// </summary>
    public int PlayersInDangerZoneCount { get; set; }

    /// <summary>
    /// 状态更新时间
    /// </summary>
    public DateTime LastUpdateTime { get; set; }
}

/// <summary>
/// 安全区域信息
/// </summary>
public class SafeZoneInfo
{
    /// <summary>
    /// 安全区域中心X坐标
    /// </summary>
    public float CenterX { get; set; }

    /// <summary>
    /// 安全区域中心Y坐标
    /// </summary>
    public float CenterY { get; set; }

    /// <summary>
    /// 安全区域半径
    /// </summary>
    public float Radius { get; set; }

    /// <summary>
    /// 区域面积
    /// </summary>
    public float Area => (float)(Math.PI * Radius * Radius);

    /// <summary>
    /// 边界点列表（用于多边形安全区）
    /// </summary>
    public List<Position> BoundaryPoints { get; set; } = new();

    /// <summary>
    /// 安全区域类型
    /// </summary>
    public SafeZoneType Type { get; set; } = SafeZoneType.Circle;
}

/// <summary>
/// 位置安全性检查结果
/// </summary>
public class PositionSafetyResult
{
    /// <summary>
    /// 位置是否安全
    /// </summary>
    public bool IsSafe { get; set; }

    /// <summary>
    /// 到安全区域边界的距离
    /// </summary>
    public float DistanceToSafeZone { get; set; }

    /// <summary>
    /// 到安全区域中心的距离
    /// </summary>
    public float DistanceToCenter { get; set; }

    /// <summary>
    /// 最近的安全位置
    /// </summary>
    public Position? NearestSafePosition { get; set; }

    /// <summary>
    /// 危险级别（0-1，1为最危险）
    /// </summary>
    public float DangerLevel { get; set; }

    /// <summary>
    /// 预计到达安全区域的时间（秒）
    /// </summary>
    public float EstimatedTimeToSafety { get; set; }
}

/// <summary>
/// 危险区域伤害处理结果
/// </summary>
public class DangerZoneDamageResult
{
    /// <summary>
    /// 处理是否成功
    /// </summary>
    public bool Success { get; set; }

    /// <summary>
    /// 玩家ID
    /// </summary>
    public Guid PlayerId { get; set; }

    /// <summary>
    /// 受到的伤害值
    /// </summary>
    public float DamageDealt { get; set; }

    /// <summary>
    /// 玩家是否死亡
    /// </summary>
    public bool PlayerDied { get; set; }

    /// <summary>
    /// 当前生命值百分比（0-1）
    /// </summary>
    public float CurrentHealthPercentage { get; set; }

    /// <summary>
    /// 在危险区域的持续时间（秒）
    /// </summary>
    public float TimeInDangerZone { get; set; }

    /// <summary>
    /// 伤害类型
    /// </summary>
    public DangerZoneDamageType DamageType { get; set; }

    /// <summary>
    /// 警告信息
    /// </summary>
    public List<string> Warnings { get; set; } = new();

    /// <summary>
    /// 错误信息
    /// </summary>
    public List<string> Errors { get; set; } = new();
}

/// <summary>
/// 受影响的领地信息
/// </summary>
public class AffectedTerritoryInfo
{
    /// <summary>
    /// 领地所有者ID
    /// </summary>
    public Guid PlayerId { get; set; }

    /// <summary>
    /// 玩家名称
    /// </summary>
    public string PlayerName { get; set; } = string.Empty;

    /// <summary>
    /// 领地边界
    /// </summary>
    public List<Position> TerritoryBoundary { get; set; } = new();

    /// <summary>
    /// 原始领地面积
    /// </summary>
    public float OriginalArea { get; set; }

    /// <summary>
    /// 剩余领地面积
    /// </summary>
    public float RemainingArea { get; set; }

    /// <summary>
    /// 损失的领地面积
    /// </summary>
    public float LostArea { get; set; }

    /// <summary>
    /// 损失百分比
    /// </summary>
    public float LossPercentage => OriginalArea > 0 ? LostArea / OriginalArea : 0;

    /// <summary>
    /// 领地是否完全消失
    /// </summary>
    public bool CompletelyEliminated { get; set; }

    /// <summary>
    /// 剩余的领地边界
    /// </summary>
    public List<Position> RemainingBoundary { get; set; } = new();
}

/// <summary>
/// 缩圈预测信息
/// </summary>
public class ShrinkingPrediction
{
    /// <summary>
    /// 缩圈阶段列表
    /// </summary>
    public List<ShrinkingStage> Stages { get; set; } = new();

    /// <summary>
    /// 总预测时间（秒）
    /// </summary>
    public int TotalDurationSeconds { get; set; }

    /// <summary>
    /// 最终安全区域大小
    /// </summary>
    public SafeZoneInfo FinalSafeZone { get; set; } = new();

    /// <summary>
    /// 高危时间点（玩家需要特别注意的时刻）
    /// </summary>
    public List<CriticalMoment> CriticalMoments { get; set; } = new();
}

/// <summary>
/// 缩圈阶段
/// </summary>
public class ShrinkingStage
{
    /// <summary>
    /// 阶段序号
    /// </summary>
    public int StageNumber { get; set; }

    /// <summary>
    /// 阶段开始时间（从缩圈开始计算的秒数）
    /// </summary>
    public int StartTime { get; set; }

    /// <summary>
    /// 阶段持续时间（秒）
    /// </summary>
    public int Duration { get; set; }

    /// <summary>
    /// 该阶段的起始安全区域
    /// </summary>
    public SafeZoneInfo StartSafeZone { get; set; } = new();

    /// <summary>
    /// 该阶段的结束安全区域
    /// </summary>
    public SafeZoneInfo EndSafeZone { get; set; } = new();

    /// <summary>
    /// 缩圈速度（半径每秒减少的像素）
    /// </summary>
    public float ShrinkingSpeed { get; set; }

    /// <summary>
    /// 该阶段的危险区域伤害
    /// </summary>
    public float DangerZoneDamage { get; set; }
}

/// <summary>
/// 关键时刻
/// </summary>
public class CriticalMoment
{
    /// <summary>
    /// 时间点（从缩圈开始计算的秒数）
    /// </summary>
    public int TimePoint { get; set; }

    /// <summary>
    /// 事件类型
    /// </summary>
    public CriticalEventType EventType { get; set; }

    /// <summary>
    /// 事件描述
    /// </summary>
    public string Description { get; set; } = string.Empty;

    /// <summary>
    /// 受影响的区域
    /// </summary>
    public SafeZoneInfo AffectedZone { get; set; } = new();

    /// <summary>
    /// 风险级别（1-5）
    /// </summary>
    public int RiskLevel { get; set; }
}

/// <summary>
/// 缩圈阶段枚举
/// </summary>
public enum ShrinkingPhase
{
    /// <summary>
    /// 未开始
    /// </summary>
    NotStarted = 0,

    /// <summary>
    /// 准备阶段 - 缩圈警告显示
    /// </summary>
    Preparing = 1,

    /// <summary>
    /// 第一阶段 - 缓慢缩圈
    /// </summary>
    Stage1 = 2,

    /// <summary>
    /// 第二阶段 - 中速缩圈
    /// </summary>
    Stage2 = 3,

    /// <summary>
    /// 最终阶段 - 快速缩圈
    /// </summary>
    FinalStage = 4,

    /// <summary>
    /// 已完成
    /// </summary>
    Completed = 5
}

/// <summary>
/// 安全区域类型
/// </summary>
public enum SafeZoneType
{
    /// <summary>
    /// 圆形安全区
    /// </summary>
    Circle = 0,

    /// <summary>
    /// 多边形安全区
    /// </summary>
    Polygon = 1
}

/// <summary>
/// 危险区域伤害类型
/// </summary>
public enum DangerZoneDamageType
{
    /// <summary>
    /// 持续伤害
    /// </summary>
    Continuous = 0,

    /// <summary>
    /// 间歇伤害
    /// </summary>
    Interval = 1,

    /// <summary>
    /// 瞬间伤害
    /// </summary>
    Instant = 2
}

/// <summary>
/// 关键事件类型
/// </summary>
public enum CriticalEventType
{
    /// <summary>
    /// 缩圈开始
    /// </summary>
    ShrinkingStart = 0,

    /// <summary>
    /// 缩圈加速
    /// </summary>
    ShrinkingAccelerate = 1,

    /// <summary>
    /// 大面积领地消失
    /// </summary>
    MassiveTerritoryLoss = 2,

    /// <summary>
    /// 最后安全区域
    /// </summary>
    FinalSafeZone = 3,

    /// <summary>
    /// 游戏即将结束
    /// </summary>
    GameEnding = 4
}
